else:
cfg['cpus'] = str(cfg['cpu'])
- # Convert 'cpus' to list of ints
+ # Convert 'cpus' to list of list of ints
+ cpus_list = []
if 'cpus' in cfg:
- cpus = []
+ # Convert the following string to list of ints.
+ # The string supports a list of ranges (0-3),
+ # seperated by commas, and negation (^1).
+ # Precedence is settled by order of the string:
+ # "0-3,^1" -> [0,2,3]
+ # "0-3,^1,1" -> [0,1,2,3]
+ def cnv(s):
+ l = []
+ for c in s.split(','):
+ if c.find('-') != -1:
+ (x, y) = c.split('-')
+ for i in range(int(x), int(y)+1):
+ l.append(int(i))
+ else:
+ # remove this element from the list
+ if c[0] == '^':
+ l = [x for x in l if x != int(c[1:])]
+ else:
+ l.append(int(c))
+ return l
+
if type(cfg['cpus']) == list:
- # If sxp_cfg was created from config.sxp,
- # the form of 'cpus' is list of string.
- # Convert 'cpus' to list of ints.
- # ['1'] -> [1]
- # ['0','2','3'] -> [0,2,3]
- try:
- for c in cfg['cpus']:
- cpus.append(int(c))
-
- cfg['cpus'] = cpus
- except ValueError, e:
- raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
+ if len(cfg['cpus']) > 0 and type(cfg['cpus'][0]) == list:
+ # If sxp_cfg was created from config.sxp,
+ # the form of 'cpus' is list of list of string.
+ # Convert 'cpus' to list of list of ints.
+ # Conversion examples:
+ # [['1']] -> [[1]]
+ # [['0','2'],['1','3']] -> [[0,2],[1,3]]
+ try:
+ for c1 in cfg['cpus']:
+ cpus = []
+ for c2 in c1:
+ cpus.append(int(c2))
+ cpus_list.append(cpus)
+ except ValueError, e:
+ raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
+ else:
+ # Conversion examples:
+ # ["1"] -> [[1]]
+ # ["0,2","1,3"] -> [[0,2],[1,3]]
+ # ["0-3,^1","1-4,^2"] -> [[0,2,3],[1,3,4]]
+ try:
+ for c in cfg['cpus']:
+ cpus = cnv(c)
+ cpus_list.append(cpus)
+ except ValueError, e:
+ raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
+
+ if len(cpus_list) != cfg['vcpus']:
+ raise XendConfigError('vcpus and the item number of cpus are not same')
else:
- # Convert 'cpus' string to list of ints
- # 'cpus' supports a list of ranges (0-3),
- # seperated by commas, and negation, (^1).
- # Precedence is settled by order of the
- # string:
- # "0-3,^1" -> [0,2,3]
- # "0-3,^1,1" -> [0,1,2,3]
+ # Conversion examples:
+ # vcpus=1:
+ # "1" -> [[1]]
+ # "0-3,^1" -> [[0,2,3]]
+ # vcpus=2:
+ # "1" -> [[1],[1]]
+ # "0-3,^1" -> [[0,2,3],[0,2,3]]
try:
- for c in cfg['cpus'].split(','):
- if c.find('-') != -1:
- (x, y) = c.split('-')
- for i in range(int(x), int(y)+1):
- cpus.append(int(i))
- else:
- # remove this element from the list
- if c[0] == '^':
- cpus = [x for x in cpus if x != int(c[1:])]
- else:
- cpus.append(int(c))
-
- cfg['cpus'] = cpus
+ cpus = cnv(cfg['cpus'])
+ for v in range(0, cfg['vcpus']):
+ cpus_list.append(cpus)
except ValueError, e:
raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
+ else:
+ # Generation examples:
+ # vcpus=1:
+ # -> [[]]
+ # vcpus=2:
+ # -> [[],[]]
+ for v in range(0, cfg['vcpus']):
+ cpus_list.append(list())
+
+ cfg['cpus'] = cpus_list
# Parse cpuid
if 'cpuid' in cfg:
raise XendInvalidDomain(str(domid))
# if vcpu is keyword 'all', apply the cpumap to all vcpus
- vcpus = [ vcpu ]
if str(vcpu).lower() == "all":
vcpus = range(0, int(dominfo.getVCpuCount()))
+ else:
+ vcpus = [ int(vcpu) ]
# set the same cpumask for all vcpus
rc = 0
- if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
- for v in vcpus:
- try:
- rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
- except Exception, ex:
- log.exception(ex)
- raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \
- (v, cpumap, str(ex)))
- else:
- # FIXME: if we could define cpu affinity definitions to
- # each vcpu, reprogram the following processing.
- if str(vcpu).lower() != "all":
- raise XendError("Must specify 'all' to VCPU "
- "for inactive managed domains")
- dominfo.setCpus(cpumap)
- self.managed_config_save(dominfo)
+ cpus = dominfo.getCpus()
+ for v in vcpus:
+ try:
+ if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
+ rc = xc.vcpu_setaffinity(dominfo.getDomid(), v, cpumap)
+ cpus[v] = cpumap
+ except Exception, ex:
+ log.exception(ex)
+ raise XendError("Cannot pin vcpu: %d to cpu: %s - %s" % \
+ (v, cpumap, str(ex)))
+ dominfo.setCpus(cpus)
+ self.managed_config_save(dominfo)
return rc
['running', 0],
['cpu_time', 0.0],
['cpu', -1],
- ['cpumap', self.info['cpus'] and \
- self.info['cpus'] or range(64)]])
+ ['cpumap', self.info['cpus'][i] and \
+ self.info['cpus'][i] or range(64)]])
return sxpr
self.info['VCPUs_live'] = vcpus
self._writeDom(self._vcpuDomDetails())
else:
+ if self.info['VCPUs_max'] > vcpus:
+ # decreasing
+ del self.info['cpus'][vcpus:]
+ elif self.info['VCPUs_max'] < vcpus:
+ # increasing
+ for c in range(self.info['VCPUs_max'], vcpus):
+ self.info['cpus'].append(list())
self.info['VCPUs_max'] = vcpus
xen.xend.XendDomain.instance().managed_config_save(self)
log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
# repin domain vcpus if a restricted cpus list is provided
# this is done prior to memory allocation to aide in memory
# distribution for NUMA systems.
- if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
+ def has_cpus():
+ if self.info['cpus'] is not None:
+ for c in self.info['cpus']:
+ if c:
+ return True
+ return False
+
+ if has_cpus():
for v in range(0, self.info['VCPUs_max']):
- xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
+ if self.info['cpus'][v]:
+ xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v])
else:
def find_relaxed_node(node_list):
import sys